package simultaneously.pattern.producer;

import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;

/**
 * notifyAll(),wait()实现
 */
class Warehouse{
    private final Queue<Integer> sharedQueue;
    private final int max_capability;
    private int pid = 0;
    public Warehouse(int capability){
        sharedQueue = new PriorityQueue<Integer>(capability);
        this.max_capability = capability;
    }
    public synchronized void produce(){
        while(sharedQueue.size() == max_capability){
            try{
                System.out.println("生产：产能过剩！等待消费！");
                wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        System.out.println("生产：制作产品"+ ++pid);
        sharedQueue.offer(pid);
        notifyAll();
    }
    public synchronized void custom(){
        while(sharedQueue.isEmpty()){
            try{
                System.out.println("消费：无产品！等待生产！");
                wait();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        System.out.println("消费：消费产品"+sharedQueue.poll());
        notifyAll();
    }
}

class Producer2 implements Runnable{
    private final Warehouse warehouse;
    public Producer2(Warehouse warehouse){
        this.warehouse  = warehouse;
    }
    public void run(){
        while (true){
            warehouse.produce();
        }
    }
}

class Customer2 implements Runnable{
    private final Warehouse warehouse;
    public Customer2(Warehouse warehouse){
        this.warehouse = warehouse;
    }
    public void run(){
        while (true){
            warehouse.custom();
        }
    }
}
public class ProducerCustomerPattern2 {
    public static void main(String[] args){
        Warehouse warehouse = new Warehouse(10);
        Thread p1 = new Thread(new Producer2(warehouse));
        Thread p2 = new Thread(new Producer2(warehouse));
        Thread c1 = new Thread(new Customer2(warehouse));
        Thread c2 = new Thread(new Customer2(warehouse));
        p1.start();
        p2.start();
        c1.start();
        c2.start();
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.exit(0);
            }
        },10);
    }
}
